Title Banner

Previous Book Contents Book Index Next

Inside Macintosh: QuickDraw GX Printing Extensions and Drivers /
Chapter 3 - Printer Drivers / Writing Printer Driver Files


Message Overrides and the Jump Table

You need to tell QuickDraw GX where (in which segment and at what offset from the beginning of that segment) to find the code for each printing message that you are overriding. You do this by defining an assembly-language jump table. The contents of the file newapp.a, which defines the jump table for the ImageWriter II printer driver,
are shown in the QuickDraw GX sample code.

The jump table links the appropriate function into your code and provides a jump statement to invoke that function. The override ('over') resource tells QuickDraw GX where to look (at which offset) in the jump table to find the jump statement for a specific printing message name. In this way, QuickDraw GX knows which of your functions to call to respond to the messages in which you are interested.

You define a jump table with one jump (JMP) statement for each message that you override. You also define an override resource that specifies the offset in that jump table for each message. The jump table and override resource must be coordinated. QuickDraw GX dispatches a printing message to your printer driver by jumping to the routine whose location is specified in the appropriate location in the jump table. The override resource is described in the section "The Override ('over') Resource" beginning on page 6-13 in the chapter "Printing Resources."

QuickDraw GX reserves the first 4 bytes for its own use, so the value of the constant firstOffset is 4. These first 4 bytes are used by QuickDraw GX to maintain an owner count and must be set to 0 in the jump table.

For example, the ImageWriter II printer driver overrides the messages that are shown in Table 3-2. This driver also overrides several Macintosh Printing Manager compatibility messages, which are not shown in this table.
Table 3-2 Printing messages overridden by the ImageWriter II printer driver
MessageWhy you override
GXInitializeTo set up the environment so that the printer driver can use predefined global values
GXShutDownTo free the storage that was allocated by the GXInitialize function
GXDefaultPrinterTo modify the default printer object characteristics, such as adding view devices that the application can use
GXDefaultJobTo modify the default job characteristics, such as which format is the default format
GXJobDefaultFormatDialogTo modify the behavior or appearance of the Page Setup dialog box
GXJobFormatModeQueryTo provide support for direct-mode printing
GXOpenConnectionTo establish connection with the printing
device
GXSetupImageDataTo modify the initialization data that is used for imaging the entire job
 
GXStartSendPageTo perform any actions required to set up printing for the next page, such as alerting the user to manually feed a piece of paper
GXRenderPageTo perform tasks during the imaging of each page
GXRasterPackageBitmapTo perform your own translation from bitmaps into character sequences for your device
GXRasterLineFeedTo send the codes to the printing device that cause it to move the print head

The override resources for the ImageWriter II printer driver must include an entry for each of these printing messages, and the jump table must include a jump statement for each. Listing 3-1 shows the override resource definitions from the newapp.r file. The override resource definition for the Macintosh Printing Manager compatibility message overrides, from the oldapp.r file, is shown in the QuickDraw GX sample code.

Listing 3-1 Two override resources from the ImageWriter II printer driver

#define firstOffset 4
#define segmentID NewSegID

resource gxOverrideType (gxDriverUniversalOverrideID, sysHeap,
                                                      purgeable)
{
   {
   gxInitialize,              segmentID, firstOffset + 0,
   gxShutDown,                segmentID, firstOffset + 4,
   gxDefaultPrinter,          segmentID, firstOffset + 8,
   gxDefaultFormat,           segmentID, firstOffset + 12,
   gxDefaultJob,              segmentID, firstOffset + 16,
   gxJobDefaultFormatDialog,  segmentID, firstOffset + 20,
   gxJobFormatModeQuery,      segmentID, firstOffset + 24
   gxRenderPage,              segmentID, firstOffset + 28,
   gxOpenConnection,          segmentID, firstOffset + 32,
   gxCloseConnection,         segmentID, firstOffset + 36
   gxStartSendPage,           segmentID, firstOffset + 40,
   gxSetupImageData,          segmentID, firstOffset + 44,
   };
};

/*
   The following are overrides for raster-specific messages, 
   including where to find them in the jump table.
*/
resource gxOverrideType (gxDriverImagingOverrideID, sysHeap)
{
   {
   gxRasterPackageBitmap,  segmentID, firstOffset + 48,
   gxRasterLineFeed,       segmentID, firstOffset + 52,
   };
};
In Listing 3-1, the name of each message is followed by the ID of the segment in which its code resides (in this case, the constant segmentID) and the byte offset of its jump statement in the jump table. QuickDraw GX reserves the first 4 bytes for its own use, so the value of the constant firstOffset is 4. These first 4 bytes are used by QuickDraw GX to maintain an owner count and must be set to 0 in the jump table.

The ImageWriter II printer driver includes two override resources for these printing messages, as shown in Listing 3-1: the first defines which universal printing messages the driver overrides, and the second defines which printing messages the driver overrides that are specific to the raster imaging system. You need to define the universal message overrides in a resource with a different ID than the resource in which you define the message overrides that are specific to the imaging system. This is described in the chapter "Printing Resources" in this book. The ImageWriter II driver also includes a third override resource for the Printing Manager compatibility messages that it overrides.

You implement the jump table as an assembly-language program that contains a jump statement for each override function. You need to list the jump statements in exactly the same order as you listed the message names in your override resource; otherwise, QuickDraw GX will invoke the wrong function in response to a message. Listing 3-2 shows the jump table for the QuickDraw GX messages found in the override resources
in the newapp.r file.

Listing 3-2 The jump table for the ImageWriter II printer driver

SD_JumpTable   PROC  EXPORT
         
         DC.L  0
         
         ; Universal messages
         IMPORT SD_Initialize
         JMP    SD_Initialize
      
         IMPORT SD_ShutDown
         JMP    SD_ShutDown
      
         IMPORT SD_DefaultPrinter
         JMP    SD_DefaultPrinter
      
         IMPORT SD_DefaultFormat
         JMP    SD_DefaultFormat
      
         IMPORT SD_DefaultJob
         JMP    SD_DefaultJob
      
         IMPORT SD_JobDefaultFormatDialog
         JMP    SD_JobDefaultFormatDialog
      
         IMPORT SD_JobFormatModeQuery
         JMP    SD_JobFormatModeQuery
      
         IMPORT SD_RenderPage
         JMP    SD_RenderPage
      
         IMPORT SD_OpenConnection
         JMP    SD_OpenConnection
      
         IMPORT SD_CloseConnection
         JMP    SD_CloseConnection

         IMPORT SD_StartSendPage
         JMP    SD_StartSendPage
      
         IMPORT SD_SetupImageData
         JMP    SD_SetupImageData
         
         ; Raster messages
         IMPORT SD_PackageBitmap
         JMP    SD_PackageBitmap
      
         IMPORT SD_LineFeed
         JMP    SD_LineFeed
         
         END
Note
The code shown in Listing 3-2 is for the MPW environment. If you are programming in a different development environment, you might need to use different assembler directives. You must, however, be certain to include the initial 4 bytes (set to 0) and each JMP statement.
The EXPORT statement at the beginning makes the jump table public. The IMPORT statements make it possible for your assembly-language program to reference the C language functions that are performing your message overrides and to provide correct linkage to those functions.

Because QuickDraw GX uses the first 4 bytes in the jump table to store the owner count value, the first statement (DC.L) must be included. These bytes must all have the value 0 in them.

The name of each override function provided by the ImageWriter II printer driver is prefixed with the string SD_ to differentiate it from other overrides of the same message. This means that the driver's override of the GXInitialize message is named SD_Initialize, its override of the GXOpenConnection message is named SD_OpenConnection, and so on.

You can choose to intersperse the IMPORT and JMP statements as shown in Listing 3-2, or you can place all of the IMPORT statements together, followed by all of the JMP statements, as is shown in Listing 2-2 on page 2-10 in the chapter "Printing Extensions."

IMPORTANT
Always coordinate the entries in your override resources with the entries in your jump table. If they are not aligned, the wrong code will be executed for a message. The offset that you specify in the resource for each message must match the offset of the corresponding function in your jump table. You must also include 4 bytes with zero values at the beginning of your jump table.

Previous Book Contents Book Index Next

© Apple Computer, Inc.
7 JUL 1996




Navigation graphic, see text links

Main | Page One | What's New | Apple Computer, Inc. | Find It | Contact Us | Help